<template>
	<div class="res-choose">
		<br />
		<el-button v-if="btnFlag" type="primary" plain icon="el-icon-copy-document" @click="openDialog">选择</el-button>
		<el-dialog
			:visible.sync="visible"
			width="1024px"
			close-on-click-modal
			append-to-body
			modal-append-to-body
			@opened="addDragEvent"
			@close="removeDragEvent"
		>
			<template #title>
				<div class="header">
					<div class="el-dialog__title">资源</div>
					<el-form inline v-show="tabActive === 'treasury'">
						<el-form-item class="el-form-item">
							<el-input type="text" placeholder="请输入图片名称" v-model="search.resourceName" clearable />
						</el-form-item>
						<el-form-item class="el-form-item">
							<el-button type="primary" @click="getData({ current: 1, size: tableData.size })" icon="el-icon-search">
								查询
							</el-button>
						</el-form-item>
					</el-form>
				</div>
			</template>

			<el-tabs v-model="tabActive" @tab-click="onTabClick">
				<el-tab-pane label="资源上传" name="upload">
					<div ref="dropBox" class="dropBox">
						<i class="el-icon-plus"></i>
						上传或拖拽文件

						<input class="input-file" type="file" @change="onFileInputChange" />
					</div>

					<div class="image-list">
						<div
							:class="['image-item', { checked: checked.url === item.url || checked.resourceUrl === item.url }]"
							v-for="(item, index) in uploadList"
							:key="index"
							@click="onChecked(item)"
						>
							<el-image
								v-if="fileType(item.url).image"
								style="width: 100%; height: 100%"
								:src="item.url"
								fit="contain"
							></el-image>
							<fortress-upload
								style="width: 100%; height: 100%"
								v-if="fileType(item.url).video"
								type="videoShow"
								name="url"
								:formData="item"
								:videoSrc="item.url"
							></fortress-upload>
							<span v-if="fileType(item.url).file">
								<el-tooltip effect="dark" :content="item.url" placement="top">
									{{ item.url }}
								</el-tooltip>
							</span>
						</div>
					</div>
				</el-tab-pane>
				<el-tab-pane label="资源库" name="treasury">
					<div class="treasury-list">
						<div
							:class="['item', { checked: checked.url === item.resourceUrl || checked.resourceUrl === item.resourceUrl }]"
							v-for="item in tableData.data"
							:key="item.id"
							@click="onChecked(item)"
						>
							<div class="item-main">
								<img
									v-if="fileType(item.resourceUrl).image"
									style="width: 100%; height: 185px; object-fit: contain"
									:src="urlFmt(item)"
								/>
								<fortress-upload
									style="width: 100%; height: 185px"
									v-if="fileType(item.resourceUrl).video"
									type="videoShow"
									name="url"
									:formData="item"
									:videoSrc="urlFmt(item)"
								></fortress-upload>
								<el-tooltip effect="dark" :content="urlFmt(item)" placement="top" v-if="fileType(item.resourceUrl).file">
									<span>
										{{ urlFmt(item) }}
									</span>
								</el-tooltip>
							</div>
							<div class="name">{{ item.resourceName }}</div>
						</div>
						<div class="item plac"></div>
						<div class="item plac"></div>
						<div class="item plac"></div>
						<div class="item plac"></div>
					</div>
					<pagination
						:total="tableData.total"
						:current-page="tableData.current"
						:page-size="tableData.size"
						@refreshData="getData"
					></pagination>
					<br />
				</el-tab-pane>
				<el-tab-pane label="提取网络图片" name="link">
					<div class="link">
						<el-input v-model="link" placeholder="图片链接" class="input"></el-input>
						<el-tag class="el-tag">
							<i class="el-icon-info"></i>
							仅支持图片资源
						</el-tag>
						<el-button type="success" @click="onTransformation">转 化</el-button>
					</div>
				</el-tab-pane>
			</el-tabs>

			<template #footer v-if="tabActive != 'link'">
				<el-button type="primary" @click="submit">确定</el-button>
				<el-button @click="visible = false">取消</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script>
import FortressPagination from "@/components/fortress-pagination.vue"
import { sysossrecordPage } from "@/api/system/sysossrecord.js"
import request from "@/common/request"

function toBlob(image) {
	var canvas = document.createElement("canvas")
	canvas.width = image.width
	canvas.height = image.height
	var ctx = canvas.getContext("2d")
	ctx.drawImage(image, 0, 0, image.width, image.height)
	const dataUrl = canvas.toDataURL("image/png")
	const arr = dataUrl.split(",")
	const mime = arr[0].match(/:(.*?);/)[1]
	const bstr = atob(arr[1])
	let n = bstr.length
	const u8arr = new Uint8Array(n)
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n)
	}
	return new Blob([u8arr], { type: mime })
}

export default {
	name: "res-choose",
	props: {
		modelName: {
			type: String,
			required: true, //require的意为必填选项
		},
		type: {
			type: String,
		},
		multiple: {
			type: Boolean,
			default: false,
		},
		btnFlag: {
			type: Boolean,
			default: true,
		},
	},
	data() {
		return {
			visible: false,
			search: {
				resourceName: "",
				resourceType: "",
				current: 1,
				size: 10,
			},
			tableData: {
				current: 1,
				size: 10,
				total: 0,
				data: [],
			},

			tabActive: "upload", // treasury link
			checked: {},
			uploadList: [],

			link: "",
		}
	},
	computed: {},
	destroyed() {
		this.removeDragEvent()
	},
	methods: {
		openDialog() {
			this.visible = true
			this.checked = {}
			this.tableData.current = 1
			this.tableData.size = 10
			this.tableData.total = 0
			this.tableData.data = []
			this.getData(this.tableData)
		},
		onTabClick() {
			if (this.tabActive === "treasury") {
				this.getData(this.tableData)
			}
		},
		async getData({ current, size }) {
			this.search.current = current
			this.search.size = size

			const { code, data, msg } = await sysossrecordPage(this.search)
			if (code != 0) {
				return this.$message.error(msg)
			}
			const { records, total } = data
			this.tableData = {
				current,
				size,
				total,
				data: records,
			}
		},
		onChecked(item) {
			this.checked = Object.assign(
				{
					resourceUrl: this.urlFmt(item),
				},
				item,
			)
		},
		submit() {
			this.$emit("choosed", this.checked, this.modelName, this.multiple)
			this.visible = false
		},

		async onUpload(file) {
			const formdata = new FormData()
			formdata.append("upfile", file)

			const { code, data, msg } = await request("post", window.$conf.commonConf.baseUrl + "/system/oss/upload", formdata)
			if (code != 0) {
				return this.$message.error(msg)
			}
			return data
		},
		addDragEvent() {
			this.$refs.dropBox.addEventListener("dragover", this.dragoverHandler)
			this.$refs.dropBox.addEventListener("dragleave", this.dragleaveHandler)
			this.$refs.dropBox.addEventListener("drop", this.dropHandler)
		},
		removeDragEvent() {
			this.$refs.dropBox && this.$refs.dropBox.removeEventListener("dragover", this.dragoverHandler)
			this.$refs.dropBox && this.$refs.dropBox.removeEventListener("dragleave", this.dragleaveHandler)
			this.$refs.dropBox && this.$refs.dropBox.removeEventListener("drop", this.dropHandler)
		},
		dragoverHandler(event) {
			event.preventDefault()
			event.stopPropagation()

			this.$refs.dropBox.classList.add("dragover")
		},
		dragleaveHandler(event) {
			event.preventDefault()
			event.stopPropagation()

			this.$refs.dropBox.classList.remove("dragover")
		},
		async onFileInputChange(event) {
			const file = event.target.files[0]
			event.target.value = null
			if (!file) return

			this.uploadList.push(await this.onUpload(file))
			this.onChecked(this.uploadList.at(-1))
		},
		async dropHandler(event) {
			event.preventDefault()
			event.stopPropagation()
			this.$refs.dropBox.classList.remove("dragover")

			if (!event.dataTransfer.files.length) {
				return
			}
			const file = event.dataTransfer.files[0]
			this.uploadList.push(await this.onUpload(file))
			this.onChecked(this.uploadList.at(-1))
		},

		onTransformation() {
			if (!this.link) return
			if (!this.fileType(this.link).image) {
				this.$message.error("非图片文件，无法转换")
				return
			}
			const image = new Image()
			const name = this.link.split("/").pop()
			image.src = this.link
			image.crossOrigin = "Anonymous"
			image.onload = async () => {
				try {
					const file = new File([toBlob(image)], name, {
						type: "image/png",
					})

					const data = await this.onUpload(file)
					this.checked = data
					this.submit()
				} catch (error) {
					console.log(error)
					this.$message.error("图片解析失败")
				}
			}
			image.onerror = () => {
				this.$message.error("链接地址请求错误")
			}
		},

		urlFmt(row) {
			return row.url ? row.url : row.resourceUrl
		},
		fileType(path) {
			const image = /\.(gif|jpg|jpeg|png|bmp|webp)$/i.test(path)
			const video = /\.(mp4|avi|rmvb|rm|asf|wmv|3gp|mkv|flv|mov|m4v)$/i.test(path)

			return {
				image,
				video,
				file: !image && !video,
			}
		},
	},
	components: {
		pagination: FortressPagination,
	},
}
</script>

<style lang="scss" scoped>
.res_choose {
	display: inline-block;
}
.header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding-right: 50px;
	height: 40px;
	.el-form-item {
		margin-bottom: 0;
	}
}
.dropBox {
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
	width: 100%;
	height: 100%;
	border: 1px dashed #d9d9d9;
	border-radius: 4px;
	cursor: pointer;
	padding: 60px 0;
	position: relative;
	transition: all 0.25s;
	&.dragover,
	&:hover {
		background: rgba(#409eff, 0.1);
		border: 1px dashed #409eff;
		color: #409eff;
		i {
			color: #409eff;
		}
	}
	i {
		font-size: 40px;
		color: #d9d9d9;
		margin-bottom: 10px;
		transition: all 0.25s;
	}
	.input-file {
		position: absolute;
		top: 0;
		bottom: 0;
		right: 0;
		left: 0;
		z-index: 5;
		opacity: 0;
		cursor: pointer;
	}
}
.image-list {
	display: flex;
	justify-content: flex-start;
	align-items: center;
	flex-wrap: wrap;
	margin-top: 20px;
	.image-item {
		width: 120px;
		height: 120px;
		display: flex;
		margin-right: 13px;
		justify-content: center;
		align-items: center;
		overflow: hidden;
		border-radius: 5px;
		border: 1px solid #d9d9d9;
		cursor: pointer;
		position: relative;
		&::before {
			content: "";
			position: absolute;
			z-index: 5;
			background: rgba(#000, 0.55);
			opacity: 0;
			top: 0;
			bottom: 0;
			right: 0;
			left: 0;
		}
		&::after {
			content: "";
			position: absolute;
			top: -5%;
			bottom: 0;
			right: 0;
			left: 0;
			width: 35px;
			height: 17px;
			border-bottom: 2px solid #fff;
			border-left: 2px solid #fff;
			transform: rotate(-45deg);
			z-index: 6;
			margin: auto;
			opacity: 0;
		}
		&.checked {
			&::before,
			&::after {
				opacity: 1;
			}
		}
	}
}
.treasury-list {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	flex-wrap: wrap;
	.item {
		width: 185px;
		height: 185px + 40 + 2;
		border: 1px solid #e0e3e9;
		overflow: hidden;
		margin-bottom: 10px;
		cursor: pointer;
		&.checked {
			.item-main {
				&::before,
				&::after {
					opacity: 1;
				}
			}
		}
		.item-main {
			width: 100%;
			height: 185px;
			position: relative;
			&::before {
				content: "";
				position: absolute;
				z-index: 5;
				background: rgba(#000, 0.55);
				opacity: 0;
				top: 0;
				bottom: 0;
				right: 0;
				left: 0;
			}
			&::after {
				content: "";
				position: absolute;
				top: -5%;
				bottom: 0;
				right: 0;
				left: 0;
				width: 35px;
				height: 17px;
				border-bottom: 2px solid #fff;
				border-left: 2px solid #fff;
				transform: rotate(-45deg);
				z-index: 6;
				margin: auto;
				opacity: 0;
			}
		}
		.name {
			background: #f5f7fa;
			color: #848485;
			text-align: center;
			line-height: 40px;
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}
		&.plac {
			visibility: hidden;
			height: 0;
			border: 0;
		}
	}
}
.link {
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
	width: 656px;
	margin: auto;
	padding: 80px 0;
	.input {
		text-align: center;
	}
	.el-tag {
		margin-top: 25px;
		margin-bottom: 25px;
	}
}
</style>
